﻿using System;
using System.Reflection;
using log4net;

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
namespace DotNet.Log
{
    public sealed class Logger
    {
        #region 单例模式
        private static Logger logger;
        private static readonly ILog logger4net = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private Logger()
        { 
            
        }
        public static Logger Singleton
        {
            get 
            {
                if (logger == null)
                {
                    logger = new Logger();
                }
                return logger;
            }
        }
        #endregion

        #region 参数

        public bool IsDebugEnabled
        {
            get { return logger4net.IsDebugEnabled; }
        }
        public bool IsInfoEnabled
        {
            get { return logger4net.IsInfoEnabled; }
        }
        public bool IsWarnEnabled
        {
            get { return logger4net.IsWarnEnabled; }
        }
        public bool IsErrorEnabled
        {
            get { return logger4net.IsErrorEnabled; }
        }
        public bool IsFatalEnabled
        {
            get { return logger4net.IsFatalEnabled; }
        }

        #endregion

        #region Debug 调试信息
        public void Debug(string message)
        {
            if (this.IsDebugEnabled)
            {
                this.Log(LogLevel.Debug, message);
            }
        }
        public void Debug(string message, Exception ex)
        {
            if (this.IsDebugEnabled)
            {
                this.Log(LogLevel.Debug, message, ex);
            }
        }
        public void Debug(string message, params object[] args)
        {
            if (this.IsDebugEnabled)
            {
                this.Log(LogLevel.Debug, message, args);
            }
        }
        public void DebugFormat(string format, params object[] args)
        {
            if (this.IsDebugEnabled)
            {
                this.Log(LogLevel.Debug, format, args);
            }
        }
        public void DebugFormat(string format, Exception ex, params object[] args)
        {
            if (this.IsDebugEnabled)
            {
                this.Log(LogLevel.Debug, string.Format(format, args), ex);
            }
        }
        #endregion

        #region Info 一般信息
        public void Info(string message)
        {
            if (this.IsInfoEnabled)
            {
                this.Log(LogLevel.Info, message);
            }
        }
        public void Info(string message, Exception ex)
        {
            if (this.IsInfoEnabled)
            {
                this.Log(LogLevel.Info, message, ex);
            }
        }
        public void Info(string message, params object[] args)
        {
            if (this.IsInfoEnabled)
            {
                this.Log(LogLevel.Info, message, args);
            }
        }
        public void InfoFormat(string format, params object[] args)
        {
            if (this.IsInfoEnabled)
            {
                this.Log(LogLevel.Info, format, args);
            }
        }
        public void InfoFormat(string format, Exception ex, params object[] args)
        {
            if (this.IsInfoEnabled)
            {
                this.Log(LogLevel.Info, string.Format(format, args), ex);
            }
        }
        #endregion

        #region Warn 警告信息
        public void Warn(string message)
        {
            if (this.IsWarnEnabled)
            {
                this.Log(LogLevel.Warn, message);
            }
        }
        public void Warn(string message, Exception ex)
        {
            if (this.IsWarnEnabled)
            {
                this.Log(LogLevel.Warn, message, ex);
            }
        }
        public void Warn(string message, params object[] args)
        {
            if (this.IsWarnEnabled)
            {
                this.Log(LogLevel.Warn, message, args);
            }
        }
        public void WarnFormat(string format, params object[] args)
        {
            if (this.IsWarnEnabled)
            {
                this.Log(LogLevel.Warn, format, args);
            }
        }
        public void WarnFormat(string format, Exception ex, params object[] args)
        {
            if (this.IsWarnEnabled)
            {
                this.Log(LogLevel.Warn, string.Format(format, args), ex);
            }
        }
        #endregion

        #region Error 错误信息
        public void Error(string message)
        {
            if (this.IsErrorEnabled)
            {
                this.Log(LogLevel.Error, message);
            }
        }
        public void Error(string message, Exception ex)
        {
            if (this.IsErrorEnabled)
            {
                this.Log(LogLevel.Error, message, ex);
            }
        }
        public void Error(string message, params object[] args)
        {
            if (this.IsErrorEnabled)
            {
                this.Log(LogLevel.Error, message, args);
            }
        }
        public void ErrorFormat(string format, params object[] args)
        {
            if (this.IsErrorEnabled)
            {
                this.Log(LogLevel.Error, format, args);
            }
        }
        public void ErrorFormat(string format, Exception ex, params object[] args)
        {
            if (this.IsErrorEnabled)
            {
                this.Log(LogLevel.Error, string.Format(format, args), ex);
            }
        }
        #endregion

        #region Fatal 致命信息
        public void Fatal(string message)
        {
            if (this.IsFatalEnabled)
            {
                this.Log(LogLevel.Fatal, message);
            }
        }
        public void Fatal(string message, Exception ex)
        {
            if (this.IsFatalEnabled)
            {
                this.Log(LogLevel.Fatal, message, ex);
            }
        }
        public void Fatal(string message, params object[] args)
        {
            if (this.IsFatalEnabled)
            {
                this.Log(LogLevel.Fatal, message, args);
            }
        }
        public void FatalFormat(string format, params object[] args)
        {
            if (this.IsFatalEnabled)
            {
                this.Log(LogLevel.Fatal, format, args);
            }
        }
        public void FatalFormat(string format, Exception ex, params object[] args)
        {
            if (this.IsFatalEnabled)
            {
                this.Log(LogLevel.Fatal, string.Format(format, args), ex);
            }
        }
        #endregion

        #region 内部方法
        /// <summary>
        /// 输出普通日志
        /// </summary>
        /// <param name="level"></param>
        /// <param name="format"></param>
        /// <param name="args"></param>
        public void Log(LogLevel level, string format, params object[] args)
        {
            switch (level)
            {
                case LogLevel.Debug:
                    logger4net.DebugFormat(format, args);
                    break;
                case LogLevel.Info:
                    logger4net.InfoFormat(format, args);
                    break;
                case LogLevel.Warn:
                    logger4net.WarnFormat(format, args);
                    break;
                case LogLevel.Error:
                    logger4net.ErrorFormat(format, args);
                    break;
                case LogLevel.Fatal:
                    logger4net.FatalFormat(format, args);
                    break;
            }
        }
        /// <summary>
        /// 格式化输出异常日志
        /// </summary>
        /// <param name="level"></param>
        /// <param name="format"></param>
        /// <param name="args"></param>
        public void Log(LogLevel level, string format, Exception ex)
        {
            switch (level)
            {
                case LogLevel.Debug:
                    logger4net.Debug(format, ex);
                    break;
                case LogLevel.Info:
                    logger4net.Info(format, ex);
                    break;
                case LogLevel.Warn:
                    logger4net.Warn(format, ex);
                    break;
                case LogLevel.Error:
                    logger4net.Error(format, ex);
                    break;
                case LogLevel.Fatal:
                    logger4net.Fatal(format, ex);
                    break;
            }
        }
        #endregion
    }

    #region 
    /// <summary>
    /// 日志级别
    /// </summary>
    public enum LogLevel
    {
        Debug,
        Info,
        Warn,
        Error,
        Fatal
    }
    #endregion
}
